package labox.innovation.gameserver.datatables;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Collection;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javolution.util.FastMap;
import labox.innovation.config.Config;
import labox.innovation.config.Server;
import labox.innovation.db.core.L2DatabaseFactory;
import labox.innovation.gameserver.Item;
import labox.innovation.gameserver.model.FuzeWorld;
import labox.innovation.gameserver.model.L2ItemInstance;
import labox.innovation.gameserver.model.L2Object;
import labox.innovation.gameserver.model.L2PetDataTable;
import labox.innovation.gameserver.model.L2ItemInstance.ItemLocation;
import labox.innovation.gameserver.model.actor.instance.FuzePcInstance;
import labox.innovation.gameserver.skills.SkillsEngine;
import labox.innovation.gameserver.templates.item.ItemCompositeConfig;
import labox.innovation.gameserver.templates.item.ItemCreateFactory;
import labox.innovation.gameserver.templates.item.ItemIdentifyConfig;
import labox.innovation.gameserver.templates.item.ItemInscribeConfig;
import labox.innovation.gameserver.templates.item.ItemRandAttribute;
import labox.innovation.gameserver.templates.item.ItemStarConfig;
import labox.innovation.gameserver.templates.item.ItemStarFactorConfig;
import labox.innovation.gameserver.templates.item.L2Armor;
import labox.innovation.gameserver.templates.item.L2EtcItem;
import labox.innovation.gameserver.templates.item.L2Item;
import labox.innovation.gameserver.templates.item.L2Weapon;
import labox.innovation.gameserver.templates.item.MobItemCreateConfig;
import labox.innovation.gameserver.templates.item.PcItemDropConfig;
import labox.innovation.gameserver.templates.item.ItemBouns.ItemBounsType;


//import labox.innovation.gameserver.util.GMAudit;

/**
 * This class ...
 *
 * @version $Revision: 1.9.2.6.2.9 $ $Date: 2005/04/02 15:57:34 $
 */
public class ItemTable {

	private static Logger _log = LoggerFactory.getLogger(ItemTable.class.getName());

	//	private static final Map<String, Integer> _materials = new FastMap<String, Integer>();
	//
	//	private static final Map<String, Integer> _crystalTypes = new FastMap<String, Integer>();
	//
	//	private static final Map<String, L2WeaponType> _weaponTypes = new FastMap<String, L2WeaponType>();
	//
	//	private static final Map<String, L2ArmorType> _armorTypes = new FastMap<String, L2ArmorType>();
	//
	//	private static final Map<String, Integer> _slots = new FastMap<String, Integer>();

	private L2Item[] _allTemplates;

	private Map<Integer, L2EtcItem> _etcItems;

	private Map<Integer, L2Armor> _armors;

	private Map<Integer, L2Weapon> _weapons;

	private boolean _initialized = true;

	//	static {
	//		_materials.put("paper", L2Item.MATERIAL_PAPER);
	//		_materials.put("wood", L2Item.MATERIAL_WOOD);
	//		_materials.put("liquid", L2Item.MATERIAL_LIQUID);
	//		_materials.put("cloth", L2Item.MATERIAL_CLOTH);
	//		_materials.put("leather", L2Item.MATERIAL_LEATHER);
	//		_materials.put("horn", L2Item.MATERIAL_HORN);
	//		_materials.put("bone", L2Item.MATERIAL_BONE);
	//		_materials.put("bronze", L2Item.MATERIAL_BRONZE);
	//		_materials.put("fine_steel", L2Item.MATERIAL_FINE_STEEL);
	//		_materials.put("cotton", L2Item.MATERIAL_FINE_STEEL);
	//		_materials.put("mithril", L2Item.MATERIAL_MITHRIL);
	//		_materials.put("silver", L2Item.MATERIAL_SILVER);
	//		_materials.put("gold", L2Item.MATERIAL_GOLD);
	//		_materials.put("adamantaite", L2Item.MATERIAL_ADAMANTAITE);
	//		_materials.put("steel", L2Item.MATERIAL_STEEL);
	//		_materials.put("oriharukon", L2Item.MATERIAL_ORIHARUKON);
	//		_materials.put("blood_steel", L2Item.MATERIAL_BLOOD_STEEL);
	//		_materials.put("crystal", L2Item.MATERIAL_CRYSTAL);
	//		_materials.put("damascus", L2Item.MATERIAL_DAMASCUS);
	//		_materials.put("chrysolite", L2Item.MATERIAL_CHRYSOLITE);
	//		_materials.put("scale_of_dragon", L2Item.MATERIAL_SCALE_OF_DRAGON);
	//		_materials.put("dyestuff", L2Item.MATERIAL_DYESTUFF);
	//		_materials.put("cobweb", L2Item.MATERIAL_COBWEB);
	//		_materials.put("seed", L2Item.MATERIAL_SEED);
	//
	//		_crystalTypes.put("s84", L2Item.CRYSTAL_S84);
	//		_crystalTypes.put("s80", L2Item.CRYSTAL_S80);
	//		_crystalTypes.put("s", L2Item.CRYSTAL_S);
	//		_crystalTypes.put("a", L2Item.CRYSTAL_A);
	//		_crystalTypes.put("b", L2Item.CRYSTAL_B);
	//		_crystalTypes.put("c", L2Item.CRYSTAL_C);
	//		_crystalTypes.put("d", L2Item.CRYSTAL_D);
	//		_crystalTypes.put("none", L2Item.CRYSTAL_NONE);
	//
	//		_weaponTypes.put("blunt", L2WeaponType.BLUNT);
	//		_weaponTypes.put("bow", L2WeaponType.BOW);
	//		_weaponTypes.put("dagger", L2WeaponType.DAGGER);
	//		_weaponTypes.put("dual", L2WeaponType.DUAL);
	//		_weaponTypes.put("dualfist", L2WeaponType.DUALFIST);
	//		_weaponTypes.put("etc", L2WeaponType.ETC);
	//		_weaponTypes.put("fist", L2WeaponType.FIST);
	//		_weaponTypes.put("none", L2WeaponType.NONE); // these are shields !  
	//		_weaponTypes.put("pole", L2WeaponType.POLE);
	//		_weaponTypes.put("sword", L2WeaponType.SWORD);
	//		_weaponTypes.put("bigsword", L2WeaponType.BIGSWORD); //Two-Handed Swords  
	//		_weaponTypes.put("pet", L2WeaponType.PET); //Pet Weapon   
	//		_weaponTypes.put("rod", L2WeaponType.ROD); //Fishing Rods  
	//		_weaponTypes.put("bigblunt", L2WeaponType.BIGBLUNT); //Two handed blunt  
	//		_weaponTypes.put("crossbow", L2WeaponType.CROSSBOW);
	//		_weaponTypes.put("rapier", L2WeaponType.RAPIER);
	//		_weaponTypes.put("ancient", L2WeaponType.ANCIENT_SWORD);
	//		_weaponTypes.put("dualdagger", L2WeaponType.DUAL_DAGGER);
	//
	//		_armorTypes.put("none", L2ArmorType.NONE);
	//		_armorTypes.put("light", L2ArmorType.LIGHT);
	//		_armorTypes.put("heavy", L2ArmorType.HEAVY);
	//		_armorTypes.put("magic", L2ArmorType.MAGIC);
	//		_armorTypes.put("pet", L2ArmorType.PET);
	//		_armorTypes.put("sigil", L2ArmorType.SIGIL);
	//
	//		_slots.put("shirt", L2Item.SLOT_UNDERWEAR);
	//		_slots.put("lbracelet", L2Item.SLOT_L_BRACELET);
	//		_slots.put("rbracelet", L2Item.SLOT_R_BRACELET);
	//		_slots.put("talisman", L2Item.SLOT_DECO);
	//		_slots.put("chest", L2Item.SLOT_CHEST);
	//		_slots.put("fullarmor", L2Item.SLOT_FULL_ARMOR);
	//		_slots.put("head", L2Item.SLOT_HEAD);
	//		_slots.put("hair", L2Item.SLOT_HAIR);
	//		_slots.put("face", L2Item.SLOT_HAIR2);
	//		_slots.put("hair2", L2Item.SLOT_HAIR2);
	//		_slots.put("dhair", L2Item.SLOT_HAIRALL);
	//		_slots.put("hairall", L2Item.SLOT_HAIRALL);
	//		_slots.put("underwear", L2Item.SLOT_UNDERWEAR);
	//		_slots.put("back", L2Item.SLOT_BACK);
	//		_slots.put("neck", L2Item.SLOT_NECK);
	//		_slots.put("legs", L2Item.SLOT_LEGS);
	//		_slots.put("feet", L2Item.SLOT_FEET);
	//		_slots.put("gloves", L2Item.SLOT_GLOVES);
	//		_slots.put("chest,legs", L2Item.SLOT_CHEST | L2Item.SLOT_LEGS);
	//		_slots.put("belt", L2Item.SLOT_BELT);
	//		_slots.put("rhand", L2Item.SLOT_R_HAND);
	//		_slots.put("lhand", L2Item.SLOT_L_HAND);
	//		_slots.put("lrhand", L2Item.SLOT_LR_HAND);
	//		_slots.put("rear,lear", L2Item.SLOT_R_EAR | L2Item.SLOT_L_EAR);
	//		_slots.put("rfinger,lfinger", L2Item.SLOT_R_FINGER | L2Item.SLOT_L_FINGER);
	//		_slots.put("wolf", L2Item.SLOT_WOLF);
	//		_slots.put("greatwolf", L2Item.SLOT_GREATWOLF);
	//		_slots.put("hatchling", L2Item.SLOT_HATCHLING);
	//		_slots.put("strider", L2Item.SLOT_STRIDER);
	//		_slots.put("babypet", L2Item.SLOT_BABYPET);
	//		_slots.put("none", L2Item.SLOT_NONE);
	//
	//	}
	
	/**
	 * Returns instance of ItemTable
	 * @return ItemTable
	 */
	public static ItemTable getInstance() {
		return SingletonHolder._instance;
	}

	/**
	 * Returns a new object Item
	 * @return
	 */
	public Item newItem() {
		return new Item();
	}

	/**
	 * Constructor.
	 */
	private ItemTable() {
		_etcItems = new FastMap<Integer, L2EtcItem>();
		_armors = new FastMap<Integer, L2Armor>();
		_weapons = new FastMap<Integer, L2Weapon>();
		load();

		//怪物装备生成配置表
		MobItemCreateConfig.getInstance().loadConfig();
		//角色掉落配置表
		PcItemDropConfig.getInstance().load();

		ItemIdentifyConfig.getInstance().loadConfig(); //鉴定配置
		ItemCompositeConfig.getInstance().loadConfig(); //合成配置
		ItemInscribeConfig.getInstance().loadConfig(); //铭刻配置
		ItemStarConfig.getInstance().loadConfig(); //追星配置
		ItemStarFactorConfig.getInstance().loadConfig();//追星结果配置

	}

	private void load() {
		/** List of etcItem */
		final Map<Integer, Item> itemData = new FastMap<Integer, Item>();
		/** List of weapons */
		final Map<Integer, Item> weaponData = new FastMap<Integer, Item>();
		/** List of armor */
		final Map<Integer, Item> armorData = new FastMap<Integer, Item>();

		//		Connection con = null;
		//		try {
		//			con = L2DatabaseFactory.getInstance().getConnection();
		//			for (String selectQuery : SQL_ITEM_SELECTS) {
		//				PreparedStatement statement = con.prepareStatement(selectQuery);
		//				ResultSet rset = statement.executeQuery();
		//
		//				// Add item in correct FastMap
		//				while (rset.next()) {
		//					if (selectQuery.endsWith("etcitem")) {
		//						Item newItem = readItem(rset);
		//						itemData.put(newItem.id, newItem);
		//					} else if (selectQuery.endsWith("armor")) {
		//						Item newItem = readArmor(rset);
		//						armorData.put(newItem.id, newItem);
		//					} else if (selectQuery.endsWith("weapon")) {
		//						Item newItem = readWeapon(rset);
		//						weaponData.put(newItem.id, newItem);
		//					}
		//				}
		//
		//				rset.close();
		//				statement.close();
		//			}
		//		} catch (Exception e) {
		//			_log.log(Level.WARNING, "data error on item: ", e);
		//		} finally {
		//			try {
		//				con.close();
		//			} catch (Exception e) {
		//			}
		//		}
		//
		//		if (Config.CUSTOM_ITEM_TABLES) {
		//			try {
		//				con = L2DatabaseFactory.getInstance().getConnection();
		//				for (String selectQuery : SQL_CUSTOM_ITEM_SELECTS) {
		//					PreparedStatement statement = con.prepareStatement(selectQuery);
		//					ResultSet rset = statement.executeQuery();
		//
		//					// Add item in correct FastMap
		//					while (rset.next()) {
		//						if (selectQuery.endsWith("etcitem")) {
		//							Item newItem = readItem(rset);
		//
		//							if (itemData.containsKey(newItem.id))
		//								itemData.remove(newItem.id);
		//
		//							itemData.put(newItem.id, newItem);
		//						} else if (selectQuery.endsWith("armor")) {
		//							Item newItem = readArmor(rset);
		//
		//							if (armorData.containsKey(newItem.id))
		//								armorData.remove(newItem.id);
		//
		//							armorData.put(newItem.id, newItem);
		//						} else if (selectQuery.endsWith("weapon")) {
		//							Item newItem = readWeapon(rset);
		//
		//							if (weaponData.containsKey(newItem.id))
		//								weaponData.remove(newItem.id);
		//
		//							weaponData.put(newItem.id, newItem);
		//						}
		//					}
		//					rset.close();
		//					statement.close();
		//				}
		//			} catch (Exception e) {
		//				_log.log(Level.WARNING, "data error on custom_item: ", e);
		//			} finally {
		//				try {
		//					con.close();
		//				} catch (Exception e) {
		//				}
		//			}
		//		}

		_armors.clear();
		for (L2Armor armor : SkillsEngine.getInstance().loadArmors(armorData)) {
			_armors.put(armor.getItemId(), armor);
		}
		if( _log.isDebugEnabled() )
			_log.debug("ItemTable: Loaded " + _armors.size() + " Armors.");

		_etcItems.clear();
		for (L2EtcItem item : SkillsEngine.getInstance().loadItems(itemData)) {
			_etcItems.put(item.getItemId(), item);
		}
		if( _log.isDebugEnabled() )
			_log.debug("ItemTable: Loaded " + _etcItems.size() + " Items.");

		_weapons.clear();
		for (L2Weapon weapon : SkillsEngine.getInstance().loadWeapons(weaponData)) {
			_weapons.put(weapon.getItemId(), weapon);
		}
		if( _log.isDebugEnabled() )
			_log.debug("ItemTable: Loaded " + _weapons.size() + " Weapons.");

		buildFastLookupTable();
	}

	/**
	 * Returns object Item from the record of the database
	 * 
	 * @param rset : ResultSet designating a record of the [weapon] table of database
	 * @return Item : object created from the database record
	 * @throws SQLException
	 */
	//	private Item readWeapon(ResultSet rset) throws SQLException {
	//		Item item = new Item();
	//		item.set = new StatsSet();
	//		item.type = _weaponTypes.get(rset.getString("weaponType"));
	//		item.id = rset.getInt("item_id");
	//		item.name = rset.getString("name");
	//
	//		item.set.set("item_id", item.id);
	//		item.set.set("name", item.name);
	//
	//		// lets see if this is a shield
	//		if (item.type == L2WeaponType.NONE) {
	//			item.set.set("type1", L2Item.TYPE1_SHIELD_ARMOR);
	//			item.set.set("type2", L2Item.TYPE2_SHIELD_ARMOR);
	//		} else {
	//			item.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
	//			item.set.set("type2", L2Item.TYPE2_WEAPON);
	//		}
	//
	//		item.set.set("bodypart", _slots.get(rset.getString("bodypart")));
	//		item.set.set("material", _materials.get(rset.getString("material")));
	//		item.set.set("crystal_type", _crystalTypes.get(rset.getString("crystal_type")));
	//		item.set.set("crystallizable", Boolean.valueOf(rset.getString("crystallizable")).booleanValue());
	//		item.set.set("weight", rset.getInt("weight"));
	//		item.set.set("soulshots", rset.getInt("soulshots"));
	//		item.set.set("spiritshots", rset.getInt("spiritshots"));
	//		item.set.set("p_dam", rset.getInt("p_dam"));
	//		item.set.set("rnd_dam", rset.getInt("rnd_dam"));
	//		item.set.set("critical", rset.getInt("critical"));
	//		item.set.set("hit_modify", rset.getDouble("hit_modify"));
	//		item.set.set("avoid_modify", rset.getInt("avoid_modify"));
	//		item.set.set("shield_def", rset.getInt("shield_def"));
	//		item.set.set("shield_def_rate", rset.getInt("shield_def_rate"));
	//		item.set.set("atk_speed", rset.getInt("atk_speed"));
	//		item.set.set("mp_consume", rset.getInt("mp_consume"));
	//		item.set.set("m_dam", rset.getInt("m_dam"));
	//		item.set.set("duration", rset.getInt("duration"));
	//		item.set.set("time", rset.getInt("time"));
	//		item.set.set("price", rset.getInt("price"));
	//		item.set.set("crystal_count", rset.getInt("crystal_count"));
	//		item.set.set("sellable", Boolean.valueOf(rset.getString("sellable")));
	//		item.set.set("dropable", Boolean.valueOf(rset.getString("dropable")));
	//		item.set.set("destroyable", Boolean.valueOf(rset.getString("destroyable")));
	//		item.set.set("tradeable", Boolean.valueOf(rset.getString("tradeable")));
	//		item.set.set("depositable", Boolean.valueOf(rset.getString("depositable")));
	//
	//		item.set.set("skill", rset.getString("skill"));
	//
	//		item.set.set("enchant4_skill_id", rset.getInt("enchant4_skill_id"));
	//		item.set.set("enchant4_skill_lvl", rset.getInt("enchant4_skill_lvl"));
	//
	//		item.set.set("onCast_skill_id", rset.getInt("onCast_skill_id"));
	//		item.set.set("onCast_skill_lvl", rset.getInt("onCast_skill_lvl"));
	//		item.set.set("onCast_skill_chance", rset.getInt("onCast_skill_chance"));
	//
	//		item.set.set("onCrit_skill_id", rset.getInt("onCrit_skill_id"));
	//		item.set.set("onCrit_skill_lvl", rset.getInt("onCrit_skill_lvl"));
	//		item.set.set("onCrit_skill_chance", rset.getInt("onCrit_skill_chance"));
	//		item.set.set("change_weaponId", rset.getInt("change_weaponId"));
	//
	//		if (item.type == L2WeaponType.PET) {
	//			item.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
	//			if (item.set.getInteger("bodypart") == L2Item.SLOT_WOLF)
	//				item.set.set("type2", L2Item.TYPE2_PET_WOLF);
	//			else if (item.set.getInteger("bodypart") == L2Item.SLOT_GREATWOLF)
	//				item.set.set("type2", L2Item.TYPE2_PET_EVOLVEDWOLF);
	//			else if (item.set.getInteger("bodypart") == L2Item.SLOT_HATCHLING)
	//				item.set.set("type2", L2Item.TYPE2_PET_HATCHLING);
	//			else if (item.set.getInteger("bodypart") == L2Item.SLOT_BABYPET)
	//				item.set.set("type2", L2Item.TYPE2_PET_BABY);
	//			else
	//				item.set.set("type2", L2Item.TYPE2_PET_STRIDER);
	//
	//			item.set.set("bodypart", L2Item.SLOT_R_HAND);
	//		}
	//
	//		return item;
	//	}

	//	/**
	//	 * Returns object Item from the record of the database
	//	 * @param rset : ResultSet designating a record of the [armor] table of database
	//	 * @return Item : object created from the database record
	//	 * @throws SQLException
	//	 */
	//	private Item readArmor(ResultSet rset) throws SQLException {
	//		Item item = new Item();
	//		item.set = new StatsSet();
	//		item.type = _armorTypes.get(rset.getString("armor_type"));
	//		item.id = rset.getInt("item_id");
	//		item.name = rset.getString("name");
	//
	//		item.set.set("item_id", item.id);
	//		item.set.set("name", item.name);
	//		int bodypart = _slots.get(rset.getString("bodypart"));
	//		item.set.set("bodypart", bodypart);
	//		item.set.set("crystallizable", Boolean.valueOf(rset.getString("crystallizable")));
	//		item.set.set("crystal_count", rset.getInt("crystal_count"));
	//		item.set.set("sellable", Boolean.valueOf(rset.getString("sellable")));
	//		item.set.set("dropable", Boolean.valueOf(rset.getString("dropable")));
	//		item.set.set("destroyable", Boolean.valueOf(rset.getString("destroyable")));
	//		item.set.set("tradeable", Boolean.valueOf(rset.getString("tradeable")));
	//		item.set.set("depositable", Boolean.valueOf(rset.getString("depositable")));
	//		item.set.set("enchant4_skill", rset.getString("enchant4_skill"));
	//		item.set.set("skill", rset.getString("skill"));
	//
	//		if (bodypart == L2Item.SLOT_NECK || bodypart == L2Item.SLOT_HAIR || bodypart == L2Item.SLOT_HAIR2 || bodypart == L2Item.SLOT_HAIRALL || (bodypart & L2Item.SLOT_L_EAR) != 0 || (bodypart & L2Item.SLOT_L_FINGER) != 0 || (bodypart & L2Item.SLOT_R_BRACELET) != 0 || (bodypart & L2Item.SLOT_L_BRACELET) != 0) {
	//			item.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
	//			item.set.set("type2", L2Item.TYPE2_ACCESSORY);
	//		} else {
	//			item.set.set("type1", L2Item.TYPE1_SHIELD_ARMOR);
	//			item.set.set("type2", L2Item.TYPE2_SHIELD_ARMOR);
	//		}
	//
	//		item.set.set("weight", rset.getInt("weight"));
	//		item.set.set("material", _materials.get(rset.getString("material")));
	//		item.set.set("crystal_type", _crystalTypes.get(rset.getString("crystal_type")));
	//		item.set.set("avoid_modify", rset.getInt("avoid_modify"));
	//		item.set.set("duration", rset.getInt("duration"));
	//		item.set.set("time", rset.getInt("time"));
	//		item.set.set("p_def", rset.getInt("p_def"));
	//		item.set.set("m_def", rset.getInt("m_def"));
	//		item.set.set("mp_bonus", rset.getInt("mp_bonus"));
	//		item.set.set("price", rset.getInt("price"));
	//
	//		if (item.type == L2ArmorType.PET) {
	//			if (bodypart == L2Item.SLOT_NECK) {
	//				item.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
	//				item.set.set("type2", L2Item.TYPE2_ACCESSORY);
	//				item.set.set("bodypart", L2Item.SLOT_NECK);
	//			} else {
	//				item.set.set("type1", L2Item.TYPE1_SHIELD_ARMOR);
	//				switch (item.set.getInteger("bodypart")) {
	//				case L2Item.SLOT_WOLF:
	//					item.set.set("type2", L2Item.TYPE2_PET_WOLF);
	//					break;
	//				case L2Item.SLOT_GREATWOLF:
	//					item.set.set("type2", L2Item.TYPE2_PET_EVOLVEDWOLF);
	//					break;
	//				case L2Item.SLOT_HATCHLING:
	//					item.set.set("type2", L2Item.TYPE2_PET_HATCHLING);
	//					break;
	//				case L2Item.SLOT_BABYPET:
	//					item.set.set("type2", L2Item.TYPE2_PET_BABY);
	//					break;
	//				default:
	//					item.set.set("type2", L2Item.TYPE2_PET_STRIDER);
	//					break;
	//				}
	//				item.set.set("bodypart", L2Item.SLOT_CHEST);
	//			}
	//		}
	//
	//		return item;
	//	}

	/**
	 * Returns object Item from the record of the database
	 * @param rset : ResultSet designating a record of the [etcitem] table of database
	 * @return Item : object created from the database record
	 * @throws SQLException
	 */
	//	private Item readItem(ResultSet rset) throws SQLException {
	//		Item item = new Item();
	//		item.set = new StatsSet();
	//		item.id = rset.getInt("item_id");
	//
	//		item.set.set("item_id", item.id);
	//		item.set.set("crystallizable", Boolean.valueOf(rset.getString("crystallizable")));
	//		item.set.set("type1", L2Item.TYPE1_ITEM_QUESTITEM_ADENA);
	//		item.set.set("type2", L2Item.TYPE2_OTHER);
	//		item.set.set("bodypart", 0);
	//		item.set.set("crystal_count", rset.getInt("crystal_count"));
	//		item.set.set("sellable", Boolean.valueOf(rset.getString("sellable")));
	//		item.set.set("dropable", Boolean.valueOf(rset.getString("dropable")));
	//		item.set.set("destroyable", Boolean.valueOf(rset.getString("destroyable")));
	//		item.set.set("tradeable", Boolean.valueOf(rset.getString("tradeable")));
	//		item.set.set("depositable", Boolean.valueOf(rset.getString("depositable")));
	//		item.set.set("handler", rset.getString("handler"));
	//		item.set.set("skill", rset.getString("skill"));
	//		String itemType = rset.getString("item_type");
	//		if (itemType.equals("none"))
	//			item.type = L2EtcItemType.OTHER; // only for default
	//		else if (itemType.equals("castle_guard"))
	//			item.type = L2EtcItemType.SCROLL; // dummy
	//		else if (itemType.equals("material"))
	//			item.type = L2EtcItemType.MATERIAL;
	//		else if (itemType.equals("pet_collar"))
	//			item.type = L2EtcItemType.PET_COLLAR;
	//		else if (itemType.equals("potion"))
	//			item.type = L2EtcItemType.POTION;
	//		else if (itemType.equals("recipe"))
	//			item.type = L2EtcItemType.RECEIPE;
	//		else if (itemType.equals("scroll"))
	//			item.type = L2EtcItemType.SCROLL;
	//		else if (itemType.equals("seed"))
	//			item.type = L2EtcItemType.SEED;
	//		else if (itemType.equals("shot"))
	//			item.type = L2EtcItemType.SHOT;
	//		else if (itemType.equals("spellbook"))
	//			item.type = L2EtcItemType.SPELLBOOK; // Spellbook, Amulet, Blueprint
	//		else if (itemType.equals("herb"))
	//			item.type = L2EtcItemType.HERB;
	//		else if (itemType.equals("arrow")) {
	//			item.type = L2EtcItemType.ARROW;
	//			item.set.set("bodypart", L2Item.SLOT_L_HAND);
	//		} else if (itemType.equals("bolt")) {
	//			item.type = L2EtcItemType.BOLT;
	//			item.set.set("bodypart", L2Item.SLOT_L_HAND);
	//		} else if (itemType.equals("quest")) {
	//			item.type = L2EtcItemType.QUEST;
	//			item.set.set("type2", L2Item.TYPE2_QUEST);
	//		} else if (itemType.equals("lure")) {
	//			item.type = L2EtcItemType.OTHER;
	//			item.set.set("bodypart", L2Item.SLOT_L_HAND);
	//		} else {
	//			_log.fine("unknown etcitem type:" + itemType);
	//			item.type = L2EtcItemType.OTHER;
	//		}
	//
	//		String consume = rset.getString("consume_type");
	//		if (consume.equals("asset")) {
	//			item.type = L2EtcItemType.MONEY;
	//			item.set.set("stackable", true);
	//			item.set.set("type2", L2Item.TYPE2_MONEY);
	//		} else if (consume.equals("stackable")) {
	//			item.set.set("stackable", true);
	//		} else {
	//			item.set.set("stackable", false);
	//		}
	//
	//		int material = _materials.get(rset.getString("material"));
	//		item.set.set("material", material);
	//
	//		int crystal = _crystalTypes.get(rset.getString("crystal_type"));
	//		item.set.set("crystal_type", crystal);
	//
	//		int weight = rset.getInt("weight");
	//		item.set.set("weight", weight);
	//		item.name = rset.getString("name");
	//		item.set.set("name", item.name);
	//
	//		item.set.set("duration", rset.getInt("duration"));
	//		item.set.set("time", rset.getInt("time"));
	//		item.set.set("price", rset.getInt("price"));
	//
	//		return item;
	//	}

	/**
	 * Returns if ItemTable initialized
	 * @return boolean
	 */
	public boolean isInitialized() {
		return _initialized;
	}

	/*
	 private void fillEtcItemsTable()
	 {
	 for (Item itemInfo : itemData.values())
	 {
	 L2EtcItem item = SkillsEngine.getInstance().loadEtcItem(itemInfo.id, itemInfo.type, itemInfo.name, itemInfo.set);
	 if (item == null)
	 {
	 item = new L2EtcItem((L2EtcItemType)itemInfo.type, itemInfo.set);
	 }

	 _etcItems.put(item.getItemId(), item);
	 }
	 }

	 private void fillArmorsTable()
	 {
	 List<L2Armor> armorList = SkillsEngine.getInstance().loadArmors(armorData);

	 /*for (Item itemInfo : armorData.values())
	 {

	 L2Armor armor = SkillsEngine.getInstance().loadArmor(itemInfo.id, itemInfo.type, itemInfo.name, itemInfo.set);
	 if (armor == null)
	 armor = new L2Armor((L2ArmorType)itemInfo.type, itemInfo.set);

	 _armors.put(armor.getItemId(), armor);
	 }*
	 }

	 private void FillWeaponsTable()
	 {

	 for (Item itemInfo : weaponData.values())
	 {
	 L2Weapon weapon = SkillsEngine.getInstance().loadWeapon(itemInfo.id, itemInfo.type, itemInfo.name, itemInfo.set);
	 if (weapon == null)
	 weapon = new L2Weapon((L2WeaponType)itemInfo.type, itemInfo.set);

	 _weapons.put(weapon.getItemId(), weapon);
	 }
	 }*/

	/**
	 * Builds a variable in which all items are putting in in function of their ID.
	 */
	private void buildFastLookupTable() {
		int highestId = 0;

		// Get highest ID of item in armor FastMap, then in weapon FastMap, and finally in etcitem FastMap
		for (L2Armor item : _armors.values()) {
			if (item.getItemId() > highestId) {
				highestId = item.getItemId();
			}
		}
		for (L2Weapon item : _weapons.values()) {
			if (item.getItemId() > highestId) {
				highestId = item.getItemId();
			}
		}
		for (L2EtcItem item : _etcItems.values()) {
			if (item.getItemId() > highestId) {
				highestId = item.getItemId();
			}
		}

		// Create a FastLookUp Table called _allTemplates of size : value of the highest item ID
		if( _log.isDebugEnabled() )
			_log.debug("Highest item id used:" + highestId);
		_allTemplates = new L2Item[highestId + 1];

		// Insert armor item in Fast Look Up Table
		for (L2Armor item : _armors.values()) {
			assert _allTemplates[item.getItemId()] == null;
			_allTemplates[item.getItemId()] = item;
		}

		// Insert weapon item in Fast Look Up Table
		for (L2Weapon item : _weapons.values()) {
			assert _allTemplates[item.getItemId()] == null;
			_allTemplates[item.getItemId()] = item;
		}

		// Insert etcItem item in Fast Look Up Table
		for (L2EtcItem item : _etcItems.values()) {
			assert _allTemplates[item.getItemId()] == null;
			_allTemplates[item.getItemId()] = item;
		}
	}

	/**
	 * Returns the item corresponding to the item ID
	 * @param id : int designating the item
	 * @return L2Item
	 */
	public L2Item getTemplate(int id) {
		if (id >= _allTemplates.length || id < 0 )
			return null;
		else
			return _allTemplates[id];
	}

	/**
	 * 在游戏世界中创建一个道具，根据是否启用掠夺模式，以及是否为掠夺处理，来决定道具是否有绑定者以及绑定的时间
	 *
	 * <B><U> Actions</U> :</B><BR><BR>
	 * <li>Create and Init the L2ItemInstance corresponding to the Item Identifier and quantity </li>
	 * <li>Add the L2ItemInstance object to _allObjects of L2world </li>
	 * <li>Logs Item creation according to log settings</li><BR><BR>
	 *
	 * @param process : String Identifier of process triggering this action
	 * @param itemId : int Item Identifier of the item to be created
	 * @param count : int Quantity of items to be created for stackable items
	 * @param actor : L2PcInstance Player requesting the item creation
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 * @return L2ItemInstance corresponding to the new item
	 */
	public L2ItemInstance createItem(String process, int itemId, int count, FuzePcInstance actor, L2Object reference) {

		return ItemCreateFactory.getInstance().createItem(process, itemId, count, actor, reference);

	}

	public L2ItemInstance createItem(String process, int itemId, int count, FuzePcInstance actor) {
		return createItem(process, itemId, count, actor, null);
	}

	/**
	 *  新增物品创建  调用物品创建工厂去实现
	 * @param process
	 * @param itemId
	 * @param count
	 * @param actor
	 * @param mobgrade : 怪物精英等级
	 * @param moblvl : 怪物等级
	 * @return
	 */
	public L2ItemInstance createItem(String process, int itemId, int count, FuzePcInstance actor, int mobgrade, int moblvl) {
		return ItemCreateFactory.getInstance().createItem(process, itemId, count, actor, null, mobgrade, moblvl);
	}

	/**
	 * 返回一个临时的使用的道具实例.<BR><BR>
	 * <U><I>Concept :</I></U><BR>
	 * Dummy item is created by setting the ID of the object in the world at null value
	 * @param itemId : int designating the item
	 * @return L2ItemInstance designating the dummy item created
	 */
	public L2ItemInstance createDummyItem(int itemId) {
		L2Item item = getTemplate(itemId);
		if (item == null)
			return null;
		L2ItemInstance temp = new L2ItemInstance(0, item);
		try {
			temp = new L2ItemInstance(0, itemId);
		} catch (ArrayIndexOutOfBoundsException e) {
			// this can happen if the item templates were not initialized
		}

		if (temp.getItem() == null) {
			_log.warn("ItemTable: Item Template missing for Id: " + itemId, Config.SERVER_ID);
		}

		return temp;
	}

	/**
	 * Destroys the L2ItemInstance.<BR><BR>
	 *
	 * <B><U> Actions</U> :</B><BR><BR>
	 * <li>Sets L2ItemInstance parameters to be unusable </li>
	 * <li>Removes the L2ItemInstance object to _allObjects of L2world </li>
	 * <li>Logs Item delettion according to log settings</li><BR><BR>
	 *
	 * @param process : String Identifier of process triggering this action
	 * @param itemId : int Item Identifier of the item to be created
	 * @param actor : L2PcInstance Player requesting the item destroy
	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
	 */
	public void destroyItem(String process, L2ItemInstance item, FuzePcInstance actor, L2Object reference) {

		item.setCount(0);
		item.setOwnerId(0);
//		item.setLocation(ItemLocation.VOID);
		item.setLocation(ItemLocation.VOID, -1);
		item.setLastChange(L2ItemInstance.REMOVED);

		//			L2World.getInstance().removeObject(item);
		FuzeWorld.getInstance().exitWorld(item);

//		if (Config.LOG_ITEMS) {
			StringBuilder sb=new StringBuilder();
			sb.append("删除物品:").append(process).append(',').append(item.getName()).append('(').append(item.getObjectId()).append(')');
			_log.info(sb.toString() , item.getObjectId(), item.getName() );
//		}

		if (actor != null) {
			if (actor.isGM()) {
				String referenceName = "no-reference";
				if (reference != null) {
					referenceName = (reference.getName() != null ? reference.getName() : "no-name");
				}
				String targetName = (actor.getTarget() != null ? actor.getTarget().getName() : "no-target");
				//					if (Config.GMAUDIT)
				//						GMAudit.auditGMAction(actor.getName(), process + "(id: " + item.getItemId() + " count: " + item.getCount() + " itemObjId: " + item.getObjectId() + ")", targetName, "L2Object referencing this action is: " + referenceName);
			}
		}

		// if it's a pet control item, delete the pet as well
		if (L2PetDataTable.isPetItem(item.getItemId())) {
			Connection con = null;
			try {
				// Delete the pet in db
				con = L2DatabaseFactory.getInstance().getConnection();
				PreparedStatement statement = con.prepareStatement("DELETE FROM pets WHERE item_obj_id=?");
				statement.setLong(1, item.getObjectId());
				statement.execute();
				statement.close();
			} catch (Exception e) {
				_log.error("could not delete pet objectid:", Config.SERVER_ID, e);
			} finally {
				try {
					con.close();
				} catch (Exception e) {
				}
			}
		}

	}

	public void reload() {
		load();
	}

	protected class resetOwner implements Runnable {
		L2ItemInstance _item;

		public resetOwner(L2ItemInstance item) {
			_item = item;
		}

		public void run() {
			_item.setOwnerId(0);
			_item.setItemLootShedule(null);
		}
	}

	public Collection<Integer> getAllArmorsId() {
		return _armors.keySet();
	}

	public Collection<Integer> getAllWeaponsId() {
		return _weapons.keySet();
	}

	@SuppressWarnings("synthetic-access")
	private static class SingletonHolder {
		protected static final ItemTable _instance = new ItemTable();
	}

	//OnlyForTest
	public static void main(String[] args) {

		Server.serverMode = Server.MODE_GAMESERVER;
		Config.load();

		ItemTable iT = ItemTable.getInstance();
		iT.load();
		//		 L2Item[] tt = iT._allTemplates;
		//		 
		//		 for( L2Item item:tt )
		//		 {
		//			 if( item != null)
		//				 item.OnlyFortest();
		//		 }

		//		 MobItemCreateConfig.getInstance().loadConfig();

		L2ItemInstance test = iT.createItem(null, 6000, 1, null, 3, 15);

		System.out.println("物品名:" + test.getItemName());
		System.out.println("物品品质:" + test.getItemGrade());
		System.out.println(test.getAttriDescriptoin());
		((ItemRandAttribute) test.getItemBouns(ItemBounsType.RAND_ATTRIBUTES.ordinal())).onlyForTest();
		System.out.println("物品附加属性:" + ((ItemRandAttribute) test.getItemBouns(ItemBounsType.RAND_ATTRIBUTES.ordinal())).getAttriNums());

	}

}
